/*
 Copyright (C) 2010 QDSS.org
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.qdss.bizz.security;

import java.io.Serializable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.qdss.bizz.privileges.DepthEntry;
import org.qdss.bizz.privileges.Permission;
import org.qdss.bizz.privileges.Privileges;
import org.qdss.bizz.privileges.impl.BizzDepthEntry;
import org.qdss.bizz.privileges.impl.BizzPermission;

/**
 * 实体权限
 * 
 * @author <a href="mailto:zhaofang123@gmail.com">Zhao Fangfang</a>
 * @since 0.2, 2010-10-4
 * @version $Id: EntityPrivileges.java 7 2011-05-15 16:40:50Z zhaofang123@gmail.com $
 */
public class EntityPrivileges implements Privileges {
	private static final long serialVersionUID = -8141823128069571526L;

	private final int entity;
	private final String definition;
	
	private final Map<DepthEntry, Permission[]> dePermissions = new HashMap<DepthEntry, Permission[]>();
	private final Set<Permission> allPermissions = new HashSet<Permission>();
	
	/**
	 * @param entity
	 * @param definition
	 * 			权限定义，各层级之间使用 <tt>,</tt> 分割，层级与权限值之间使用 <tt>:</tt> 分割。
	 * 			<pre>
	 * 			如 <i>1:15,2:15,3:8,4:0</i> 其意为：
	 * 			<i>1:15</i> 其中 <i>1</i> 表示私人，<i>15</i> 是动作值的累加（本例中的动作是 15 = 1+2+4+8），
	 * 			即对应 <i>增 + 删 + 改 + 查</i>
	 * 			以此类推，具体值定义参考类 {@link BizzPermission}, {@link BizzDepthEntry}
	 * 			</pre>
	 */
	public EntityPrivileges(int entity, String definition) {
		this.entity = entity;
		this.definition = definition;
		
		String depthValues[] = definition.split(",");
		for (String dv : depthValues) {
			String dpVal[] = dv.split(":");
			
			Permission[] perms = BizzPermission.parse(Integer.valueOf(dpVal[1]));
			for (Permission p : perms)
				allPermissions.add(p);
			dePermissions.put(
					BizzDepthEntry.parse(Integer.valueOf(dpVal[0])), perms);
		}
	}
	
	@Override
	public boolean allowed(Permission action) {
		return allPermissions.contains(action);
	}

	/**
	 * Always throw UnsupportedOperationException
	 */
	@Override
	public boolean allowed(Permission action, Serializable targetGuard) {
		throw new UnsupportedOperationException();
	}

	@Override
	public DepthEntry superlative(Permission action) {
		Set<DepthEntry> set = new HashSet<DepthEntry>(dePermissions.size());
		for (Map.Entry<DepthEntry, Permission[]> e : dePermissions.entrySet()) {
			for (Permission p : e.getValue()) {
				if (action.equals(p)) {
					set.add(e.getKey());
					break;
				}
			}
		}
		
		if (set.isEmpty())
			return BizzDepthEntry.NONE;
		
		DepthEntry sup = BizzDepthEntry.NONE;
		for (DepthEntry de : set) {
			if (de.getMask() > sup.getMask())
				sup = de;
			
			if (BizzDepthEntry.GLOBAL.equals(sup))
				return BizzDepthEntry.GLOBAL;
		}
		return sup;
	}
	
	/**
	 * 获取此权限所属的实体
	 * 
	 * @return
	 */
	public int getEntity() {
		return entity;
	}
	
	/**
	 * 获取表示此权限的原始字符串
	 * 
	 * @return
	 */
	public String getDefinition() {
		return definition;
	}
}
